#include "iceclient.h"
#include "ObjIdentify.h"




IceClient::IceClient(QObject *parent) : QObject(parent)
{
    kModelWidth =224;
    kModelHeight = 224;
    chn =3;
    deviceID =0;
    ModelPath = "";
}

// 请求算法信息，平台信息
int IceClient::request(int type,  QStringList &info)
{
#ifdef ICE_STATIC_LIBS
    Ice::registerIceSSL();
    Ice::registerIceUDP();
    Ice::registerIceWS();
#endif

    try
    {
        QString configFile;
        switch(cp){

            case DK200:
                configFile = QString("config200dk.client");
                break;
            case FPGA:
                configFile = QString("configFpga.client");
                break;

        }

        Ice::CommunicatorHolder ich(configFile.toStdString());
        auto communicator = ich.communicator();

        auto  objIdentify =Ice::uncheckedCast<ObjIdentifyPrx>(communicator->propertyToProxy("Classify.Proxy"));
        if (type == 1)
        {
            kModelWidth = 416;
            kModelHeight = 416;
            ModelPath = "../yolov3_ice/model/yolov3_hands.om";
            objIdentify =Ice::uncheckedCast<ObjIdentifyPrx>(communicator->propertyToProxy("Detect.Proxy"));
        }
         else if (type == 2)
        {
            kModelWidth = 224;
            kModelHeight = 224;
            ModelPath = "../acl_classification/model/mobilenetv2_new.om";

        }else if(type == 3){
            kModelWidth = 416;
            kModelHeight = 416;
            ModelPath = "../src/data/Parameters.bin";
            WeightPath = "../src/data/Weight.bin";
            objIdentify =Ice::uncheckedCast<ObjIdentifyPrx>(communicator->propertyToProxy("Detect.Proxy"));

        }
        else
        {
            cout<<"parameter error"<<endl;
        }


        if (!objIdentify)
        {
            throw "Invalid proxy";
        }

        //objIdentify->SetDevice(deviceID);
        //objIdentify->SetModelPath(ModelPath, WeightPath);
        ::IdentifyModule::AlgorithmInfo algo_info = objIdentify->GetAlgorithmInfo();
        cout << "Contents of GetAlgorithmInfo:" << endl;
        cout << "name=" << algo_info.name << endl;
        cout << "version=" << algo_info.version << endl;
        info<< QString::fromStdString( algo_info.name) <<QString::fromStdString( algo_info.version);

    }
    catch(const std::exception& ex)
    {
        cerr << ex.what() << endl;
        return -1;
    }
    return 0;
}

void IceClient::setComputingPlatform(ComputingPlatform param)
{
    cp = param;
}

int IceClient::request(int type, Mat frame ,::IdentifyModule::BboxSeq &objKind)
{
#ifdef ICE_STATIC_LIBS
    Ice::registerIceSSL();
    Ice::registerIceUDP();
    Ice::registerIceWS();
#endif

    try
    {
        QString configFile;
        switch(cp){

            case DK200:
                configFile = QString("config200dk.client");
                break;
            case FPGA:
                configFile = QString("configFpga.client");
                break;

        }

        Ice::CommunicatorHolder ich(configFile.toStdString());
        auto communicator = ich.communicator();
        auto objIdentify =Ice::uncheckedCast<ObjIdentifyPrx>(communicator->propertyToProxy("Detect.Proxy"));
        if (type == 1)
        {

             kModelWidth = 416;
             kModelHeight = 416;
             ModelPath = "../yolov3_ice/model/yolov3_hands.om";
        }
         else if (type == 2)
        {
            kModelWidth = 224;
            kModelHeight = 224;
            ModelPath = "../acl_classification/model/mobilenetv2_new.om";
            objIdentify =Ice::uncheckedCast<ObjIdentifyPrx>(communicator->propertyToProxy("Classify.Proxy"));

        }else if(type == 3){
            kModelWidth = 416;
            kModelHeight = 416;
            ModelPath = "../src/data/Parameters.bin";
            WeightPath = "../src/data/Weight.bin";
            objIdentify =Ice::uncheckedCast<ObjIdentifyPrx>(communicator->propertyToProxy("Detect.Proxy"));

        }
        else
        {
            cout<<"parameter error"<<endl;
        }




        if (!objIdentify)
        {
            throw "Invalid proxy";
        }

        objIdentify->SetDevice(deviceID);
        objIdentify->SetModelPath(ModelPath, WeightPath);

        ::IdentifyModule::Row Img;
        imgToRow(frame, Img);

        objKind = objIdentify->GetObjBbox(Img);
        cout << "Contents of getObjKinds:" << endl;
        for (int i = 0; i < objKind.size(); i++)
        {
            cout << "name=" << objKind[i].name << endl;
            cout << "confidence=" << objKind[i].confidence << endl;
            cout << "position= ( " << objKind[i].rect.left << "," << objKind[i].rect.top << ",";
            cout << objKind[i].rect.right << "," << objKind[i].rect.bottom << ")" << endl;
        }

    }
    catch(const std::exception& ex)
    {
        cerr << ex.what() << endl;
        return -1;
    }
    return 0;


}


int IceClient::request(int type, string file ,::IdentifyModule::BboxSeq &objKind)
{
#ifdef ICE_STATIC_LIBS
    Ice::registerIceSSL();
    Ice::registerIceUDP();
    Ice::registerIceWS();
#endif

    try
    {
        QString configFile;
        switch(cp){

            case DK200:
                configFile = QString("config200dk.client");
                break;
            case FPGA:
                configFile = QString("configFpga.client");
                break;

        }
        cout<< configFile.toStdString() <<endl;
        Ice::CommunicatorHolder ich(configFile.toStdString());
        auto communicator = ich.communicator();

        auto  objIdentify =Ice::uncheckedCast<ObjIdentifyPrx>(communicator->propertyToProxy("Classify.Proxy"));
        if (type == 1)
        {

             kModelWidth = 416;
             kModelHeight = 416;
             ModelPath = "../yolov3_ice/model/yolov3_hands.om";
             objIdentify =Ice::uncheckedCast<ObjIdentifyPrx>(communicator->propertyToProxy("Detect.Proxy"));
        }
         else if (type == 2)
        {
            kModelWidth = 224;
            kModelHeight = 224;
            ModelPath = "../acl_classification/model/mobilenetv2_new.om";

        }else if(type == 3){
            kModelWidth = 416;
            kModelHeight = 416;
            ModelPath = "../src/data/Parameters.bin";
            WeightPath = "../src/data/Weight.bin";
            objIdentify =Ice::uncheckedCast<ObjIdentifyPrx>(communicator->propertyToProxy("Detect.Proxy"));

        }
        else
        {
            cout<<"parameter error"<<endl;
        }

        if (!objIdentify)
        {
            throw "Invalid proxy";
        }

        objIdentify->SetDevice(deviceID);
        objIdentify->SetModelPath(ModelPath, WeightPath);

        ::IdentifyModule::Row Img;
        imgToRow(file, Img);

        objKind = objIdentify->GetObjBbox(Img);
        cout << "Contents of getObjKinds:" << endl;
        for (int i = 0; i < objKind.size(); i++)
        {
            cout << "name=" << objKind[i].name << endl;
            cout << "confidence=" << objKind[i].confidence << endl;
            cout << "position= ( " << objKind[i].rect.left << "," << objKind[i].rect.top << ",";
            cout << objKind[i].rect.right << "," << objKind[i].rect.bottom << ")" << endl;
        }

    }
    catch(const std::exception& ex)
    {
        cerr << ex.what() << endl;
        return 0;
    }
    return 0;

}





void IceClient::imgToRow(Mat frame, Row &img_Row)
{
          cv::Mat img ;
          cv::resize(frame, img, cv::Size(kModelWidth, kModelHeight));
          int imgSize = kModelWidth * kModelHeight * 3;

          int idxR = 0;
          int idxG = kModelWidth * kModelHeight;
          int idxB = idxG * 2;

          img_Row.resize(imgSize);

          for (int i = 0; i < kModelWidth; ++i)  // rows
          {
                  cv::Vec3b *p = img.ptr<cv::Vec3b>(i);  // ¿i¿
                  char curValue;

                  for (int j = 0; j < kModelHeight; ++j)  // ¿¿¿i¿¿¿¿¿
                  {
                          // ¿¿cell¿¿¿¿¿¿B,G,R
                          curValue = p[j][2];  // R
                         img_Row[idxR++] = curValue;

                          curValue = p[j][1];  // G
                          img_Row[idxG++] = curValue;

                          curValue = p[j][0];  // B
                          img_Row[idxB++] = curValue;
                  }
         }
}

void IceClient::imgToRow(string imgfilepath, Row &img_Row)
{
          cv::Mat img = cv::imread(imgfilepath);
          cv::resize(img, img, cv::Size(kModelWidth, kModelHeight));
          int imgSize = kModelWidth * kModelHeight * 3;

          int idxR = 0;
          int idxG = kModelWidth * kModelHeight;
          int idxB = idxG * 2;

          img_Row.resize(imgSize);

          for (int i = 0; i < kModelWidth; ++i)  // rows
          {
                  cv::Vec3b *p = img.ptr<cv::Vec3b>(i);  // ¿i¿
                  char curValue;

                  for (int j = 0; j < kModelHeight; ++j)  // ¿¿¿i¿¿¿¿¿
                  {
                          curValue = p[j][2];  // R
                         img_Row[idxR++] = curValue;

                          curValue = p[j][1];  // G
                          img_Row[idxG++] = curValue;

                          curValue = p[j][0];  // B
                          img_Row[idxB++] = curValue;
                  }
         }
}

